
#include "gamecontrol.h"

GameControl* GameControl::instance = nullptr;

GameControl::GameControl()
{

}

GameControl *GameControl::Instance()
{
    if(instance == nullptr)
    {
        return instance = new GameControl();
    }
}
GameControl::~GameControl()
{
    if(instance != nullptr)
        delete instance;
    instance = nullptr;
}

void GameControl::setParent(Widget *Parent)
{
    this->parent = Parent;
}

void GameControl::GameInit()
{
    mGameView.setSceneRect(QRect(0,0,GameDefine::ScreenWidth,GameDefine::ScreenHeight));//游戏主界面大小
    LoadMS();//加载谱面文件
    CreateTimer();//创建计时器
    LoadStartScene();//初始化开始场景
    LoadMainScene();//初始化主场景
    LoadEndScene();//初始化结算场景

    //添加场景到视图
    mGameView.setScene(&mStartScene);//先显示开始场景
    mGameView.setParent(parent);//设置视图的父类
    mGameView.show();
}

void GameControl::LoadMS()
{
    //打开谱面文件
    mMS = new MusicScore(parent);
    mMS->InitByFile(GameDefine::MSAddress);
}

void GameControl::LoadStartScene()
{
    //初始化主界面和开始场景
    mStartScene.setSceneRect(QRect(0,0,GameDefine::ScreenWidth,GameDefine::ScreenHeight));//场景大小
    mStartScene.setBackgroundBrush (QBrush(qRgb (0,0,0)));//场景颜色

    //未完成的gif添加
    //gif1.resize(256,103);
    //Gifplayer1.setVideoOutput(&gif1);//添加显示器
    //Gifplayer1.setSource(QUrl(":/gif/xinhaichigua.gif"));//设置播放视频
    //Gifplayer1.play();
    //videoWidget = new QVideoWidget(this);
    //videoWidget->resize(500, 300);
    //player->setVideoOutput(videoWidget);

    LoadStartPushbutton();//PushButton初始化
    LoadStartAddPicture();//添加元素图片
    LoadStartPos();//元素位置设定
    LoadStartAddItem();//元素添加到场景
    TimerConnect();//按钮、定时器功能连接
}

void GameControl::LoadStartPos()
{
    //初始化各个元素的位置
    mStartBackground.setPos(0,0);
    mTitle1.setPos(237,50);
    mTitle2.setPos(134,259);
    mTitle3->move(151,380);
    // player.setPosition(qint64());
}

void GameControl::LoadStartAddItem()
{
    //将各个元素添加到初始场景中
    mStartScene.addItem(&mStartBackground);
    mStartScene.addItem(&mTitle1);
    mStartScene.addItem(&mTitle2);
    mStartScene.addWidget(mTitle3);
    // mStartScene.addItem(&gif1);
}

void GameControl::LoadStartAddPicture()
{
    //给背景和轨道设置图片
    mTitle1.setPixmap(QPixmap(":/img/Title1.png"));
    mTitle2.setPixmap(QPixmap(":/img/Title2.png"));
    mTitle3->setIcon(QIcon(":/img/Title4.png"));
}

void GameControl::LoadStartPushbutton()
{
    //PushButton创建
    mTitle3 = new QPushButton();
    mTitle3->resize(498,75);
    mTitle3->setIconSize(QSize(498,75));

}

void GameControl::LoadMainScene()
{
    mMainScene.setSceneRect(QRect(0,0,GameDefine::ScreenWidth,GameDefine::ScreenHeight));//场景大小
    mMainScene.setBackgroundBrush (QBrush(qRgb (0,0,0)));//场景颜色
    LoadMainSettingItems();
    LoadMainAddPicture();
    LoadMainPos();
    LoadMainAddItem();
}

void GameControl::LoadMainAddItem()
{
    mMainScene.addItem(&mBackground);//设置背景图到场景
    mMainScene.addItem(&mTrack1);//设置轨道到场景
    mMainScene.addItem(&mTrack2);
    mMainScene.addItem(&mTrack3);
    mMainScene.addItem(&mTrack4);
    mMainScene.addItem(mPoints);//设置分数标签到场景
    mMainScene.addItem(mLv);//设置难度标签到场景
    mMainScene.addItem(mPName);//设置谱面名称标签到场景
    mMainScene.addItem(mCombo);//设置Combo标签到场景
    mMainScene.addItem(mComboNum);//设置连击数标签到场景
    mMainScene.addItem(mStatus);//设置状态显示到场景
}

void GameControl::LoadMainAddPicture()
{
    //给背景和轨道设置图片
    mTrack1.setPixmap(QPixmap(":/img/TrackC75.png"));
    mTrack2.setPixmap(QPixmap(":/img/TrackC75.png"));
    mTrack3.setPixmap(QPixmap(":/img/TrackC75.png"));
    mTrack4.setPixmap(QPixmap(":/img/TrackC75.png"));
    mBackground.setPixmap(QPixmap(mMS->BackGround));
    LoadMainAddEffect();
    mBackground.setGraphicsEffect(mBGBlurEffect);
    mBackground.setGraphicsEffect(mBGOpacityEffect);
}

void GameControl::LoadMainAddEffect()
{
    mBGBlurEffect = new QGraphicsBlurEffect(parent);//模糊效果
    mBGBlurEffect->setBlurRadius(30);

    mBGOpacityEffect = new QGraphicsOpacityEffect(parent);//透明效果
    mBGOpacityEffect->setOpacity(0.7);
}

void GameControl::LoadMainSettingItems()
{
    //初始化分数
    mPoints = new QGraphicsTextItem;
    mPoints->setPlainText(QString("%1").arg(mMS->points, 7, 10, QLatin1Char('0')));
    mPoints->setDefaultTextColor(QColor(255,255,255));//颜色
    mPoints->setFont(QFont("Courier New",23,100));//字体

    //初始化难度
    mLv = new QGraphicsTextItem;
    mLv->setPlainText(QString("Lv.%1").arg(mMS->level));
    mLv->setDefaultTextColor(QColor(255,255,255));//颜色
    mLv->setFont(QFont("Courier New",20,60));//字体

    //初始化谱面名称
    mPName = new QGraphicsTextItem;
    mPName->setPlainText(mMS->name);
    mPName->setDefaultTextColor(QColor(255,255,255));//颜色
    mPName->setFont(QFont("Courier New",14,80));//字体

    //初始化combo标签
    mCombo->setDefaultTextColor(QColor(255,255,255));//颜色
    mCombo->setFont(QFont("Dosis",50,80));//字体

    //初始化连击数
    mComboNum = new QGraphicsTextItem;
    mComboNum->setPlainText(QString("%1").arg(mMS->ComboNum));//初状态连击数
    mComboNum->setDefaultTextColor(QColor(255,255,255));//颜色
    mComboNum->setFont(QFont("Dosis",45,80));//字体

    //状态显示
    mStatus = new QGraphicsTextItem;
    mStatus->setFont(QFont("Dosis",30,80));//字体
}

void GameControl::LoadMainPos()
{
    //初始化各个元素的位置
    mBackground.setPos(0,0);
    mTrack1.setPos(300,0);//各轨道位置
    mTrack2.setPos(380,0);
    mTrack3.setPos(460,0);
    mTrack4.setPos(540,0);
    mPoints->setPos(640,0);//分数位置
    mLv->setPos(700,565);//难度位置
    mPName->setPos(5,565);//谱面名称位置
    mCombo->setPos(60,150);
    qreal width1 = mCombo->boundingRect().width();//"Combo"宽度
    qreal width2 = mComboNum->boundingRect().width();//ComboNum宽度
    mComboNum->setPos(60+width1/2-width2/2,230);//初始化ComboNum位置(居中)
}

void GameControl::LoadEndScene()
{
    mEndScene.setSceneRect(QRect(0,0,GameDefine::ScreenWidth,GameDefine::ScreenHeight));//场景大小
    mEndScene.setBackgroundBrush (QBrush(qRgb (0,0,0)));//场景颜色
    LoadEndBGM();
    LoadEndAddPicture();
    LoadEndPos();
    LoadEndAddItem();
}

void GameControl::LoadEndBGM()
{
    //初始化背景音乐
    EndBGMPlayer = new QMediaPlayer(this);
    EndBGMPlayer->setSource(QUrl("qrc:/audio/EndBGM.mp3"));
    EndBGMPlayer->setLoops(-1);//设置循环播放
    EndBGMOutput = new QAudioOutput(this);
    EndBGMOutput->setVolume(0.3);
    EndBGMPlayer->setAudioOutput(EndBGMOutput);
}

void GameControl::LoadEndAddItem()
{
    mEndScene.addItem(&mEndBackground);//设置背景图到场景
    mEndScene.addItem(&mEndRect);
    mEndScene.addItem(&mRank);
    mEndScene.addItem(mEndName);
    mEndScene.addItem(mScore);
    mEndScene.addItem(mMaxCombo);
    mEndScene.addItem(mMaxComboNum);
    mEndScene.addItem(mAccuracy);
    mEndScene.addItem(mAccuracyNum);
    mEndScene.addItem(mPerfect);
    mEndScene.addItem(mPerfectNum);
    mEndScene.addItem(mGood);
    mEndScene.addItem(mGoodNum);
    mEndScene.addItem(mBad);
    mEndScene.addItem(mBadNum);
    mEndScene.addItem(mMiss);
    mEndScene.addItem(mMissNum);
}

void GameControl::LoadEndAddEffect()
{
    mEBGBlurEffect = new QGraphicsBlurEffect(this);//模糊效果
    mEBGBlurEffect->setBlurRadius(30);

    mEBGOpacityEffect = new QGraphicsOpacityEffect;//透明效果
    mEBGOpacityEffect->setOpacity(0.7);
}

void GameControl::LoadEndAddPicture()
{
    //初始化背景
    mEndBackground.setPixmap(QPixmap(mMS->BackGround));
    LoadEndAddEffect();
    mEndBackground.setGraphicsEffect(mEBGBlurEffect);
    mEndBackground.setGraphicsEffect(mEBGOpacityEffect);

    //初始化矩形
    mEndRect.setPixmap(QPixmap(":/img/EndBackGround.png"));

    //初始化谱名
    mEndName = new QGraphicsTextItem;
    mEndName->setPlainText(mMS->name);
    mEndName->setDefaultTextColor(QColor(255,255,255));//颜色
    mEndName->setFont(QFont("Courier New",30,80));//字体

    //初始化分数
    mScore = new QGraphicsTextItem;
    mScore->setDefaultTextColor(QColor(255,255,255));//颜色
    mScore->setFont(QFont("Courier New",50,80));//字体

    //初始化最大连击数
    mMaxCombo->setDefaultTextColor(QColor(255,255,255));//颜色
    mMaxCombo->setFont(QFont("Dosis",15,80));//字体

    mMaxComboNum = new QGraphicsTextItem;
    mMaxComboNum->setDefaultTextColor(QColor(255,255,255));//颜色
    mMaxComboNum->setFont(QFont("Courier New",30,80));//字体

    //初始化准度
    mAccuracy->setDefaultTextColor(QColor(255,255,255));//颜色
    mAccuracy->setFont(QFont("Dosis",15,80));//字体

    mAccuracyNum = new QGraphicsTextItem;
    mAccuracyNum->setDefaultTextColor(QColor(255,255,255));//颜色
    mAccuracyNum->setFont(QFont("Courier New",30,80));//字体

    //初始化P
    mPerfect->setDefaultTextColor(QColor(255,255,255));//颜色
    mPerfect->setFont(QFont("Dosis",15,80));//字体

    mPerfectNum = new QGraphicsTextItem;
    mPerfectNum->setDefaultTextColor(QColor(255,255,255));//颜色
    mPerfectNum->setFont(QFont("Courier New",30,80));//字体

    //初始化G
    mGood->setDefaultTextColor(QColor(255,255,255));//颜色
    mGood->setFont(QFont("Dosis",15,80));//字体

    mGoodNum = new QGraphicsTextItem;
    mGoodNum->setDefaultTextColor(QColor(255,255,255));//颜色
    mGoodNum->setFont(QFont("Courier New",30,80));//字体

    //初始化B
    mBad->setDefaultTextColor(QColor(255,255,255));//颜色
    mBad->setFont(QFont("Dosis",15,80));//字体

    mBadNum = new QGraphicsTextItem;
    mBadNum->setDefaultTextColor(QColor(255,255,255));//颜色
    mBadNum->setFont(QFont("Courier New",30,80));//字体

    //初始化M
    mMiss->setDefaultTextColor(QColor(255,255,255));//颜色
    mMiss->setFont(QFont("Dosis",15,80));//字体

    mMissNum = new QGraphicsTextItem;
    mMissNum->setDefaultTextColor(QColor(255,255,255));//颜色
    mMissNum->setFont(QFont("Courier New",30,80));//字体

}

void GameControl::LoadEndPos()
{
    mEndRect.setPos(0,100);//矩形位置
    mRank.setPos(50,150);//Rank位置
    mEndName->setPos(5,100);//谱面名称位置
    mScore->setPos(400,170);//分数位置
    mMaxCombo->setPos(300,270);//最大连击数名称位置
    mMaxComboNum->setPos(360,300);//最大连击数位置
    mAccuracy->setPos(550,270);//准度名称位置
    mAccuracyNum->setPos(610,300);//准度位置
    mPerfect->setPos(5,400);//P名称位置
    mPerfectNum->setPos(50,425);//P位置
    mGood->setPos(200,400);//G名称位置
    mGoodNum->setPos(250,425);//G位置
    mBad->setPos(400,400);//B名称位置
    mBadNum->setPos(450,425);//B位置
    mMiss->setPos(600,400);//M名称位置
    mMissNum->setPos(650,425);//M位置
}

void GameControl::CreateTimer()
{
    //创建计时器
    mMSTimer = new QTimer(parent);
    mDelay = new QTimer(parent);
    mDetectKeyTimer = new QTimer(parent);
    mBorder = new QTimer(parent);
    BGMDelay = new QTimer(parent);
    MSDelay = new QTimer(parent);
}

void GameControl::TimerConnect()
{
    //按钮跳转事件和谱面计时器打开事件
    connect(mTitle3,&QToolButton::clicked,[this]{
        mGameView.setScene(&mMainScene);

        //mGameView.setScene(&mEndScene);//test
        // mMS->JudgeRank();//test
        // mRank.setPixmap(QPixmap(mMS->Rank));//test


        mGameView.show();
        mDelay->start(GameDefine::MSDelay);//设置3秒缓冲
        BGMDelay->start(GameDefine::Delay);//设置1.5秒缓冲
    });
    //缓冲时间到后
    connect(mDelay,&QTimer::timeout,[this](){
        mMSTimer->start(GameDefine::MSTime);//打开谱面计时器
        mDetectKeyTimer->start(GameDefine::Border);//打开判定检测器
        MSDelay->start(mMS->MusicLenth+GameDefine::EndDelay);
        mMS->setparent(&mMainScene);//添加谱面至场景
        mDelay->stop();
    });

    //BGM缓冲计时器
    connect(BGMDelay,&QTimer::timeout,[this](){\
            mMS->BGMPlayer->play();
        BGMDelay->stop();
    });

    //谱面计时器
    connect(mMSTimer,&QTimer::timeout,[this](){
        mMS->notesMove(mMS->speed);
    });

    //判定计时器
    connect(mDetectKeyTimer,&QTimer::timeout,this,&GameControl::judgeStatus);
    connect(mDetectKeyTimer,&QTimer::timeout,this,&GameControl::ShowStatus);//显示状态
    connect(mDetectKeyTimer,&QTimer::timeout,this,&GameControl::ShowComboNum);//显示连击数
    connect(mDetectKeyTimer,&QTimer::timeout,this,&GameControl::ShowPoints);//显示分数
    //边界判定
    connect(mDetectKeyTimer,&QTimer::timeout,[this](){
        mMS->JudgeBorder(&mMainScene);
    });

    //最终界面跳转计时器
    connect(MSDelay,&QTimer::timeout,[this]{
        mGameView.setScene(&mEndScene);
        ResetEnddata();
        EndBGMPlayer->play();//播放结算音乐
        mGameView.show();
    });
}

void GameControl::judgeStatus()
{
    for(int keyCode : parent->mKeyList){
        switch(keyCode){
        case Qt::Key_S:
        {
            mMS->status = mMS->JudgeStatus(1,&mMainScene);//按键S->1轨道
            parent->mKeyList.removeOne(Qt::Key_S);
            break;
        }
        case Qt::Key_D:
        {
            mMS->status = mMS->JudgeStatus(2,&mMainScene);//按键D->2轨道
            parent->mKeyList.removeOne(Qt::Key_D);
            break;
        }
        case Qt::Key_J:
        {
            mMS->status = mMS->JudgeStatus(3,&mMainScene);//按键J->3轨道
            parent->mKeyList.removeOne(Qt::Key_J);
            break;
        }
        case Qt::Key_K:
        {
            mMS->status = mMS->JudgeStatus(4,&mMainScene);//按键K->4轨道
            parent->mKeyList.removeOne(Qt::Key_K);
            break;
        }
        }
    }
}

void GameControl::ShowStatus()
{
    QString Status;
    switch(mMS->status){
    case 0:
    {
        Status = " ";
        mStatus->setPos(80,300);//状态显示位置
        break;
    }
    case 1:
    {
        Status = "Perfect";
        mStatus->setDefaultTextColor(QColor(255,222,3));//颜色
        mStatus->setPos(80,300);//状态显示位置
        break;
    }
    case 2:
    {
        Status = "Good";
        mStatus->setDefaultTextColor(QColor(160,255,255));//颜色
        mStatus->setPos(105,300);//状态显示位置
        break;
    }
    case 3:
    {
        Status = "Bad";
        mStatus->setDefaultTextColor(QColor(255,255,255));//颜色
        mStatus->setPos(117,300);//状态显示位置
        break;
    }
    case 4:
    {
        Status = "Miss";
        mStatus->setDefaultTextColor(QColor(255,255,255));//颜色
        mStatus->setPos(108,300);//状态显示位置
        break;
    }
    }
    mStatus->setPlainText(Status);
}

void GameControl::ShowComboNum()
{
    mComboNum->setPlainText(QString("%1").arg(mMS->ComboNum));
}

void GameControl::ShowPoints()
{
    mMS->CalculatePoints();
    mPoints->setPlainText(QString("%1").arg(mMS->points, 7, 10, QLatin1Char('0')));
}

void GameControl::ResetEnddata()
{
    mMS->JudgeRank();
    mRank.setPixmap(QPixmap(mMS->Rank));
    mScore->setPlainText(QString("%1").arg(mMS->points, 7, 10, QLatin1Char('0')));
    mMaxComboNum->setPlainText(QString("%1").arg(mMS->MaxComboNum));
    mAccuracyNum->setPlainText(QString("%1%").arg(mMS->acc*100,0,'g',4));
    mPerfectNum->setPlainText(QString("%1").arg(mMS->PerfectNum));
    mGoodNum->setPlainText(QString("%1").arg(mMS->GoodNum));
    mBadNum->setPlainText(QString("%1").arg(mMS->BadNum));
    mMissNum->setPlainText(QString("%1").arg(mMS->MissNum));
}
